home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / conproc.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-13  |  8.5 KB  |  432 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // conproc.c -- support for qhost
  21. #include <stdio.h>
  22. #include <process.h>
  23. #include <windows.h>
  24. #include "conproc.h"
  25.  
  26. #define CCOM_WRITE_TEXT        0x2
  27. // Param1 : Text
  28.  
  29. #define CCOM_GET_TEXT        0x3
  30. // Param1 : Begin line
  31. // Param2 : End line
  32.  
  33. #define CCOM_GET_SCR_LINES    0x4
  34. // No params
  35.  
  36. #define CCOM_SET_SCR_LINES    0x5
  37. // Param1 : Number of lines
  38.  
  39.  
  40. HANDLE    heventDone;
  41. HANDLE    hfileBuffer;
  42. HANDLE    heventChildSend;
  43. HANDLE    heventParentSend;
  44. HANDLE    hStdout;
  45. HANDLE    hStdin;
  46.  
  47. unsigned _stdcall RequestProc (void *arg);
  48. LPVOID GetMappedBuffer (HANDLE hfileBuffer);
  49. void ReleaseMappedBuffer (LPVOID pBuffer);
  50. BOOL GetScreenBufferLines (int *piLines);
  51. BOOL SetScreenBufferLines (int iLines);
  52. BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine);
  53. BOOL WriteText (LPCTSTR szText);
  54. int CharToCode (char c);
  55. BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy);
  56.  
  57. int        ccom_argc;
  58. char    **ccom_argv;
  59.  
  60. /*
  61. ================
  62. CCheckParm
  63.  
  64. Returns the position (1 to argc-1) in the program's argument list
  65. where the given parameter apears, or 0 if not present
  66. ================
  67. */
  68. int CCheckParm (char *parm)
  69. {
  70.     int             i;
  71.     
  72.     for (i=1 ; i<ccom_argc ; i++)
  73.     {
  74.         if (!ccom_argv[i])
  75.             continue;
  76.         if (!strcmp (parm,ccom_argv[i]))
  77.             return i;
  78.     }
  79.         
  80.     return 0;
  81. }
  82.  
  83.  
  84. void InitConProc (int argc, char **argv)
  85. {
  86.     unsigned    threadAddr;
  87.     HANDLE        hFile;
  88.     HANDLE        heventParent;
  89.     HANDLE        heventChild;
  90.     int            t;
  91.  
  92.     ccom_argc = argc;
  93.     ccom_argv = argv;
  94.  
  95. // give QHOST a chance to hook into the console
  96.     if ((t = CCheckParm ("-HFILE")) > 0)
  97.     {
  98.         if (t < argc)
  99.             hFile = (HANDLE)atoi (ccom_argv[t+1]);
  100.     }
  101.         
  102.     if ((t = CCheckParm ("-HPARENT")) > 0)
  103.     {
  104.         if (t < argc)
  105.             heventParent = (HANDLE)atoi (ccom_argv[t+1]);
  106.     }
  107.         
  108.     if ((t = CCheckParm ("-HCHILD")) > 0)
  109.     {
  110.         if (t < argc)
  111.             heventChild = (HANDLE)atoi (ccom_argv[t+1]);
  112.     }
  113.  
  114.  
  115. // ignore if we don't have all the events.
  116.     if (!hFile || !heventParent || !heventChild)
  117.     {
  118.         printf ("Qhost not present.\n");
  119.         return;
  120.     }
  121.  
  122.     printf ("Initializing for qhost.\n");
  123.  
  124.     hfileBuffer = hFile;
  125.     heventParentSend = heventParent;
  126.     heventChildSend = heventChild;
  127.  
  128. // so we'll know when to go away.
  129.     heventDone = CreateEvent (NULL, FALSE, FALSE, NULL);
  130.  
  131.     if (!heventDone)
  132.     {
  133.         printf ("Couldn't create heventDone\n");
  134.         return;
  135.     }
  136.  
  137.     if (!_beginthreadex (NULL, 0, RequestProc, NULL, 0, &threadAddr))
  138.     {
  139.         CloseHandle (heventDone);
  140.         printf ("Couldn't create QHOST thread\n");
  141.         return;
  142.     }
  143.  
  144. // save off the input/output handles.
  145.     hStdout = GetStdHandle (STD_OUTPUT_HANDLE);
  146.     hStdin = GetStdHandle (STD_INPUT_HANDLE);
  147.  
  148. // force 80 character width, at least 25 character height
  149.     SetConsoleCXCY (hStdout, 80, 25);
  150. }
  151.  
  152.  
  153. void DeinitConProc (void)
  154. {
  155.     if (heventDone)
  156.         SetEvent (heventDone);
  157. }
  158.  
  159.  
  160. unsigned _stdcall RequestProc (void *arg)
  161. {
  162.     int        *pBuffer;
  163.     DWORD    dwRet;
  164.     HANDLE    heventWait[2];
  165.     int        iBeginLine, iEndLine;
  166.     
  167.     heventWait[0] = heventParentSend;
  168.     heventWait[1] = heventDone;
  169.  
  170.     while (1)
  171.     {
  172.         dwRet = WaitForMultipleObjects (2, heventWait, FALSE, INFINITE);
  173.  
  174.     // heventDone fired, so we're exiting.
  175.         if (dwRet == WAIT_OBJECT_0 + 1)    
  176.             break;
  177.  
  178.         pBuffer = (int *) GetMappedBuffer (hfileBuffer);
  179.         
  180.     // hfileBuffer is invalid.  Just leave.
  181.         if (!pBuffer)
  182.         {
  183.             printf ("Invalid hfileBuffer\n");
  184.             break;
  185.         }
  186.  
  187.         switch (pBuffer[0])
  188.         {
  189.             case CCOM_WRITE_TEXT:
  190.             // Param1 : Text
  191.                 pBuffer[0] = WriteText ((LPCTSTR) (pBuffer + 1));
  192.                 break;
  193.  
  194.             case CCOM_GET_TEXT:
  195.             // Param1 : Begin line
  196.             // Param2 : End line
  197.                 iBeginLine = pBuffer[1];
  198.                 iEndLine = pBuffer[2];
  199.                 pBuffer[0] = ReadText ((LPTSTR) (pBuffer + 1), iBeginLine, 
  200.                                        iEndLine);
  201.                 break;
  202.  
  203.             case CCOM_GET_SCR_LINES:
  204.             // No params
  205.                 pBuffer[0] = GetScreenBufferLines (&pBuffer[1]);
  206.                 break;
  207.  
  208.             case CCOM_SET_SCR_LINES:
  209.             // Param1 : Number of lines
  210.                 pBuffer[0] = SetScreenBufferLines (pBuffer[1]);
  211.                 break;
  212.         }
  213.  
  214.         ReleaseMappedBuffer (pBuffer);
  215.         SetEvent (heventChildSend);
  216.     }
  217.  
  218.     _endthreadex (0);
  219.     return 0;
  220. }
  221.  
  222.  
  223. LPVOID GetMappedBuffer (HANDLE hfileBuffer)
  224. {
  225.     LPVOID pBuffer;
  226.  
  227.     pBuffer = MapViewOfFile (hfileBuffer,
  228.                             FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
  229.  
  230.     return pBuffer;
  231. }
  232.  
  233.  
  234. void ReleaseMappedBuffer (LPVOID pBuffer)
  235. {
  236.     UnmapViewOfFile (pBuffer);
  237. }
  238.  
  239.  
  240. BOOL GetScreenBufferLines (int *piLines)
  241. {
  242.     CONSOLE_SCREEN_BUFFER_INFO    info;                              
  243.     BOOL                        bRet;
  244.  
  245.     bRet = GetConsoleScreenBufferInfo (hStdout, &info);
  246.         
  247.     if (bRet)
  248.         *piLines = info.dwSize.Y;
  249.  
  250.     return bRet;
  251. }
  252.  
  253.  
  254. BOOL SetScreenBufferLines (int iLines)
  255. {
  256.  
  257.     return SetConsoleCXCY (hStdout, 80, iLines);
  258. }
  259.  
  260.  
  261. BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine)
  262. {
  263.     COORD    coord;
  264.     DWORD    dwRead;
  265.     BOOL    bRet;
  266.  
  267.     coord.X = 0;
  268.     coord.Y = iBeginLine;
  269.  
  270.     bRet = ReadConsoleOutputCharacter(
  271.         hStdout,
  272.         pszText,
  273.         80 * (iEndLine - iBeginLine + 1),
  274.         coord,
  275.         &dwRead);
  276.  
  277.     // Make sure it's null terminated.
  278.     if (bRet)
  279.         pszText[dwRead] = '\0';
  280.  
  281.     return bRet;
  282. }
  283.  
  284.  
  285. BOOL WriteText (LPCTSTR szText)
  286. {
  287.     DWORD            dwWritten;
  288.     INPUT_RECORD    rec;
  289.     char            upper, *sz;
  290.  
  291.     sz = (LPTSTR) szText;
  292.  
  293.     while (*sz)
  294.     {
  295.     // 13 is the code for a carriage return (\n) instead of 10.
  296.         if (*sz == 10)
  297.             *sz = 13;
  298.  
  299.         upper = toupper(*sz);
  300.  
  301.         rec.EventType = KEY_EVENT;
  302.         rec.Event.KeyEvent.bKeyDown = TRUE;
  303.         rec.Event.KeyEvent.wRepeatCount = 1;
  304.         rec.Event.KeyEvent.wVirtualKeyCode = upper;
  305.         rec.Event.KeyEvent.wVirtualScanCode = CharToCode (*sz);
  306.         rec.Event.KeyEvent.uChar.AsciiChar = *sz;
  307.         rec.Event.KeyEvent.uChar.UnicodeChar = *sz;
  308.         rec.Event.KeyEvent.dwControlKeyState = isupper(*sz) ? 0x80 : 0x0; 
  309.  
  310.         WriteConsoleInput(
  311.             hStdin,
  312.             &rec,
  313.             1,
  314.             &dwWritten);
  315.  
  316.         rec.Event.KeyEvent.bKeyDown = FALSE;
  317.  
  318.         WriteConsoleInput(
  319.             hStdin,
  320.             &rec,
  321.             1,
  322.             &dwWritten);
  323.  
  324.         sz++;
  325.     }
  326.  
  327.     return TRUE;
  328. }
  329.  
  330.  
  331. int CharToCode (char c)
  332. {
  333.     char upper;
  334.         
  335.     upper = toupper(c);
  336.  
  337.     switch (c)
  338.     {
  339.         case 13:
  340.             return 28;
  341.  
  342.         default:
  343.             break;
  344.     }
  345.  
  346.     if (isalpha(c))
  347.         return (30 + upper - 65); 
  348.  
  349.     if (isdigit(c))
  350.         return (1 + upper - 47);
  351.  
  352.     return c;
  353. }
  354.  
  355.  
  356. BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy)
  357. {
  358.     CONSOLE_SCREEN_BUFFER_INFO    info;
  359.     COORD                        coordMax;
  360.  
  361.     coordMax = GetLargestConsoleWindowSize(hStdout);
  362.  
  363.     if (cy > coordMax.Y)
  364.         cy = coordMax.Y;
  365.  
  366.     if (cx > coordMax.X)
  367.         cx = coordMax.X;
  368.  
  369.     if (!GetConsoleScreenBufferInfo(hStdout, &info))
  370.         return FALSE;
  371.  
  372. // height
  373.     info.srWindow.Left = 0;         
  374.     info.srWindow.Right = info.dwSize.X - 1;                
  375.     info.srWindow.Top = 0;
  376.     info.srWindow.Bottom = cy - 1;          
  377.  
  378.     if (cy < info.dwSize.Y)
  379.     {
  380.         if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  381.             return FALSE;
  382.  
  383.         info.dwSize.Y = cy;
  384.  
  385.         if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  386.             return FALSE;
  387.     }
  388.     else if (cy > info.dwSize.Y)
  389.     {
  390.         info.dwSize.Y = cy;
  391.  
  392.         if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  393.             return FALSE;
  394.  
  395.         if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  396.             return FALSE;
  397.     }
  398.  
  399.     if (!GetConsoleScreenBufferInfo(hStdout, &info))
  400.         return FALSE;
  401.  
  402. // width
  403.     info.srWindow.Left = 0;         
  404.     info.srWindow.Right = cx - 1;
  405.     info.srWindow.Top = 0;
  406.     info.srWindow.Bottom = info.dwSize.Y - 1;               
  407.  
  408.     if (cx < info.dwSize.X)
  409.     {
  410.         if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  411.             return FALSE;
  412.  
  413.         info.dwSize.X = cx;
  414.     
  415.         if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  416.             return FALSE;
  417.     }
  418.     else if (cx > info.dwSize.X)
  419.     {
  420.         info.dwSize.X = cx;
  421.  
  422.         if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  423.             return FALSE;
  424.  
  425.         if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  426.             return FALSE;
  427.     }
  428.  
  429.     return TRUE;
  430. }
  431.      
  432.